// ------------------------------------------------------------------------------------------
// Licensed by Interprise Solutions.
// http://www.InterpriseSolutions.com
// For details on this license please visit  the product homepage at the URL above.
// THE ABOVE NOTICE MUST REMAIN INTACT.
// ------------------------------------------------------------------------------------------
using System.Data;
using System.Web;
using System.Data.SqlClient;
using System.Text.RegularExpressions;
using System.Collections.Generic;
using System.Linq;

namespace InterpriseSuiteEcommerceCommon
{
	/// <summary>
	/// Summary description for SE.
	/// </summary>
	public class SE
	{
		public SE()	{}

        public static string MakeEntityLink(string EntityName, string EntityID, string SEName)
		{
			if (SEName == null) { SEName = string.Empty; }

            string tmp = string.Empty;
            if (SEName.Length != 0)
            {
                tmp = MungeName(SEName);
            }
            else
            {
                tmp = SE.GetEntitySEName(EntityName, EntityID);
            }

            string URL = string.Format("{0}-{1}-{2}.aspx", EntityName.Substring(0, 1).ToLowerInvariant(), EntityID.ToString(), tmp);
			return URL.ToLowerInvariant();
		}

		public static string MakeCategoryLink(string CategoryID, string SEName)
		{
			return MakeEntityLink("Category",CategoryID,SEName);
		}

        public static string MakeSectionLink(string DepartmentID, string SEName)
		{
            //return MakeEntityLink("Section",DepartmentID,SEName);
            return MakeEntityLink("Department", DepartmentID, SEName);
		}

        public static string MakeManufacturerLink(string ManufacturerID, string SEName)
        {
            return MakeEntityLink("Manufacturer", ManufacturerID, SEName);
        }

        public static string MakeAttributeLink(string AttributeID, string SEName)
        {
            return MakeEntityLink("Attribute", AttributeID, SEName);
        }

		public static string MakeObjectLink(string ObjectName, string ObjectID, string SEName)
		{
			if (SEName == null)
			{
				SEName = string.Empty;
			}
			string URL = string.Empty;
			string tmp = string.Empty;
				if(SEName.Length != 0)
				{
                    tmp = CommonLogic.Left(Security.UrlEncode(SE.MungeName(SEName)), 90);
				}
				else
				{
					tmp = SE.GetObjectSEName(ObjectName,ObjectID);
				}
				URL = string.Format("{0}-{1}-{2}.aspx","p",ObjectID.ToString(),tmp);

			return URL.ToLowerInvariant();
		}

		public static string MakeProductLink(string ProductID, string SEName)
		{
			return MakeObjectLink("Product",ProductID,SEName);
		}

		public static string MakeObjectAndEntityLink(string ObjectName, string EntityName, string ObjectID, string EntityID, string SEName)
		{
			if (SEName == null)
			{
				SEName = string.Empty;
			}
			string URL = string.Empty;
			string tmp = string.Empty;
				if(SEName.Length != 0)
				{
					tmp = MungeName(SEName);
				}
				else
				{
					tmp = SE.GetObjectSEName(ObjectName,ObjectID);
				}
                URL = string.Format("{0}-{2}-{4}.aspx", ObjectName.Substring(0, 1), EntityName.Substring(0, 1), ObjectID.ToString(), EntityID.ToString(), tmp);
			
			return URL.ToLowerInvariant();
		}

		public static string MakeProductAndEntityLink(string EntityName, string ProductID, string EntityID, string SEName)
		{
			return MakeObjectAndEntityLink("Product",EntityName,ProductID,EntityID,SEName);
		}

		public static string MakeProductAndCategoryLink(string ProductID, string CategoryID, string SEName)
		{

			return MakeProductAndEntityLink("Category",ProductID,CategoryID,SEName);
		}

        public static string MakeProductAndSectionLink(string ProductID, string DepartmentID, string SEName)
		{
            //return MakeProductAndEntityLink("Section",ProductID,DepartmentID,SEName);
            return MakeProductAndEntityLink("Department", ProductID, DepartmentID, SEName);
		}

        public static string MakeDriverLink(string TopicName)
        {
            string URL = string.Empty;
            URL = string.Format("t-{0}.aspx", TopicName);

            return URL.ToLowerInvariant();
        }

        public static string MakeDriver2Link(string TopicName)
        {
            string URL = string.Empty;
            
            URL = string.Format("t2-{0}.aspx", TopicName);
            
            return URL.ToLowerInvariant();
        }

        public static string GetEntitySEName(string EntityName, string EntityID)
		{
			string uname = string.Empty;
            //exit when condition not satisfied to reduce nesting
            if (EntityID == string.Empty) { return CommonLogic.Left(Security.UrlEncode(SE.MungeName(uname)), 90); }
			
			if(EntityName == "Product" || EntityName == "ProductVariant")
			{
				// must do it the "hard" way ;)
                string tmpFieldName1;
                string tmpFieldName2;
                string _sql;

                switch (EntityName.ToLower())
                {
                    case "product":
                        tmpFieldName1 = "ItemCode as Name";
                        tmpFieldName2 = "IsNull(ItemDescription,ItemName) as SEName";
                        EntityName = "EcommerceViewProduct";
                        break;
                    default:
                        tmpFieldName1 = "Name";
                        tmpFieldName2 = "SEName";
                        break;
                }

                _sql = string.Format("SELECT {0}, {1} FROM {2} with (NOLOCK) WHERE Counter={3} AND ShortString = {4} AND WebSiteCode = {5}", 
                                                            tmpFieldName1, tmpFieldName2, EntityName, EntityID.ToString(),
                                                            DB.SQuote(Customer.Current.LocaleSetting), DB.SQuote(InterpriseHelper.ConfigInstance.WebSiteCode));

                using (var con = DB.NewSqlConnection())
                {
                    con.Open();
                    using (var rs = DB.GetRSFormat(con, _sql))
                    {
                        if (rs.Read())
                        {
                            uname = DB.RSField(rs, "SEName");
                            if (uname.Length == 0)
                            {
                                uname = DB.RSFieldByLocale(rs, "Name", Localization.GetUSLocale()); // SENames are ALWAYS from U.S locale
                                //update the SEName Field since it's empty
                                DB.ExecuteSQL(string.Format("update " + EntityName + " set SEName={0} where Counter={1}", DB.SQuote(CommonLogic.Left(SE.MungeName(uname), 90)), EntityID));
                            }
                        }
                    }
                }
			}
			else
			{
                string tmpFieldName1_2;
                string tmpFieldName2_2;

                switch (EntityName.ToLower())
                {
                    case "category":
                        tmpFieldName1_2 = "CategoryCode as Name";
                        tmpFieldName2_2 = "CategoryCode as SEName";
                        EntityName = "SystemCategory";
                        break;
                    //case "section":
                    case "department":  
                        tmpFieldName1_2 = "DepartmentCode as Name";
                        tmpFieldName2_2 = "DepartmentCode as SEName";
                        EntityName = "InventorySellingDepartment";
                        break;
                    case "manufacturer":
                        tmpFieldName1_2 = "ManufacturerCode AS Name";
                        tmpFieldName2_2 = "ManufacturerCode AS SEName";
                        EntityName = "SystemManufacturer";
                        break;
                    case "attribute":                                                        
                        tmpFieldName1_2 = "SourceFilterName as Name";
                        tmpFieldName2_2 = "SourceFilterName as SEName";
                        EntityName = "SystemItemAttributeSourceFilterValue";
                        break;
                    default:
                        tmpFieldName1_2 = "Name";
                        tmpFieldName2_2 = "SEName";
                        break;
                }

                using (SqlConnection con = DB.NewSqlConnection())
                {
                    con.Open();
                    using (IDataReader rs = DB.GetRSFormat(con, "select " + tmpFieldName1_2 + ", " + tmpFieldName2_2 + " from " + EntityName + " with (NOLOCK) where Counter=" + EntityID.ToString()))
                    {
                        if (rs.Read())
                        {
                            uname = DB.RSField(rs, "SEName");
                            if (uname.Length == 0)
                            {
                                uname = DB.RSFieldByLocale(rs, "Name", Localization.GetUSLocale());
                                
                                //update the SEName Field since it's empty
                                DB.ExecuteSQL(string.Format("update " + EntityName + " set SEName={0} where Counter={1}", DB.SQuote(CommonLogic.Left(SE.MungeName(uname), 90)), EntityID));
                            }
                        }
                    }
                }
			}
			
            return CommonLogic.Left(Security.UrlEncode(SE.MungeName(uname)), 90);
		}

        public static IEnumerable<KeyValuePair<string, string>> GetEntitySENameLinkList(string EntityName, IEnumerable<string> EntityIDs)
        {
            string uname = string.Empty;

            if (EntityIDs == null) return null;

            var listKeySeNameLinks = new List<KeyValuePair<string, string>>();
            string forQueryIDs = string.Join(",", EntityIDs.ToArray());

            if (EntityName == "Product" || EntityName == "ProductVariant")
            {
                // must do it the "hard" way ;)
                string tmpFieldName1;
                string tmpFieldName2;
                string _sql;

                switch (EntityName.ToLower())
                {
                    case "product":
                        tmpFieldName1 = "ItemCode as Name";
                        tmpFieldName2 = "IsNull(ItemDescription,ItemName) as SEName";
                        EntityName = "EcommerceViewProduct";
                        break;
                    default:
                        tmpFieldName1 = "Name";
                        tmpFieldName2 = "SEName";
                        break;
                }

                _sql = string.Format("SELECT Counter, {0}, {1} FROM {2} WITH (NOLOCK) WHERE Counter IN ({3}) AND ShortString = {4} AND WebSiteCode = {5}",
                                                            tmpFieldName1, tmpFieldName2, EntityName, forQueryIDs,
                                                            DB.SQuote(Customer.Current.LocaleSetting), 
                                                            DB.SQuote(InterpriseHelper.ConfigInstance.WebSiteCode));

                using (var con = DB.NewSqlConnection())
                {
                    con.Open();
                    using (var rs = DB.GetRSFormat(con, _sql))
                    {
                        while (rs.Read())
                        {
                            int EntityID = DB.RSFieldInt(rs, "Counter");
                            uname = DB.RSField(rs, "SEName");
                            if (uname.Length == 0)
                            {
                                uname = DB.RSFieldByLocale(rs, "Name", Localization.GetUSLocale()); // SENames are ALWAYS from U.S locale
                                //update the SEName Field since it's empty
                                DB.ExecuteSQL(string.Format("UPDATE {0} SET SEName={1} WHERE Counter= {2}", EntityName, DB.SQuote(CommonLogic.Left(SE.MungeName(uname), 90)), EntityID));
                            }
                            listKeySeNameLinks.Add(new KeyValuePair<string, string>(DB.RSField(rs, "Counter"), MakeEntityLink(EntityName, EntityID.ToString(), uname)));
                        }
                    }
                }
            }
            else
            {
                string tmpFieldName1_2;
                string tmpFieldName2_2;

                switch (EntityName.ToLower())
                {
                    case "category":
                        tmpFieldName1_2 = "CategoryCode as Name";
                        tmpFieldName2_2 = "CategoryCode as SEName";
                        EntityName = "SystemCategory";
                        break;
                    case "department":
                        tmpFieldName1_2 = "DepartmentCode as Name";
                        tmpFieldName2_2 = "DepartmentCode as SEName";
                        EntityName = "InventorySellingDepartment";
                        break;
                    case "manufacturer":
                        tmpFieldName1_2 = "ManufacturerCode AS Name";
                        tmpFieldName2_2 = "ManufacturerCode AS SEName";
                        EntityName = "SystemManufacturer";
                        break;
                    case "attribute":
                        tmpFieldName1_2 = "SourceFilterName as Name";
                        tmpFieldName2_2 = "SourceFilterName as SEName";
                        EntityName = "SystemItemAttributeSourceFilterValue";
                        break;
                    default:
                        tmpFieldName1_2 = "Name";
                        tmpFieldName2_2 = "SEName";
                        break;
                }

                using (var con = DB.NewSqlConnection())
                {
                    con.Open();
                    using (var rs = DB.GetRSFormat(con, "SELECT Counter, {0}, {1} FROM {2} WITH (NOLOCK) WHERE Counter IN ({3})", tmpFieldName1_2, tmpFieldName2_2, EntityName, forQueryIDs))
                    {
                        while (rs.Read())
                        {
                            int EntityID = DB.RSFieldInt(rs, "Counter");
                            uname = DB.RSField(rs, "SEName");
                            if (uname.Length == 0) 
                            {
                                uname = DB.RSFieldByLocale(rs, "Name", Localization.GetUSLocale());
                                DB.ExecuteSQL(string.Format("UPDATE {0} SET SEName={1} WHERE Counter= {2}", EntityName, DB.SQuote(CommonLogic.Left(SE.MungeName(uname), 90)), EntityID));
                            }
                            listKeySeNameLinks.Add(new KeyValuePair<string, string>(EntityID.ToString(), MakeEntityLink(EntityName, EntityID.ToString(), uname)));
                        }
                    }
                }
            }

            return listKeySeNameLinks.AsEnumerable();
        }

		public static string GetCategorySEName(string CategoryID)
		{
			return GetEntitySEName("Category",CategoryID);
		}

		public static string GetManufacturerSEName(string ManufacturerID)
		{
			return GetEntitySEName("Manufacturer",ManufacturerID);
		}

        public static string GetSectionSEName(string DepartmentID)
		{
            //return GetEntitySEName("Department",DepartmentID);
            return GetEntitySEName("Department", DepartmentID);
		}

		public static string GetObjectSEName(string ObjectName, string ObjectID)
		{
			return GetEntitySEName(ObjectName,ObjectID); // Object table may not technically an entity, but this works fine for this usage
		}

		public static string GetProductSEName(string ProductID)
		{
			return GetEntitySEName("Product",ProductID); // Product table is not technically an entity, but this works fine for this usage
		}

		public static string GetVariantSEName(string VariantID)
		{
			return GetEntitySEName("ProductVariant",VariantID); // ProductVariant table is not technically an entity, but this works fine for this usage
		}

        public static string MungeName(string str)
		{
            string otherFormat = "[\\.\\@\\$\\%\\^\\*\\]\\&\\!\\+\\=\\#\\[\\~\\`\\(\\)]";
            string regex = "[^a-z0-9-_ ]";
            string strToFormat = Regex.Replace(str.Trim().ToLowerInvariant(), otherFormat, "");
            strToFormat = Regex.Replace(strToFormat.Trim().ToLowerInvariant(), regex, "-").Replace(" ", "-");
            while (strToFormat.IndexOf("--") != -1) { strToFormat = strToFormat.Replace("--", "-"); }
            while (strToFormat.IndexOf("__") != -1) { strToFormat = strToFormat.Replace("__", "_"); }
            return HttpUtility.UrlEncode(strToFormat);
		}

	}
}



